use chrono::Utc;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use super::policy_db_model::Model;

// Policy struct, represents a policy object
#[derive(Debug, Clone, Serialize, Deserialize)]
/// Policy id, uuid
pub struct Policy {
    pub id: Uuid,
    /// Policy name
    pub name: String,
    /// Policy description
    pub description: String,
    /// Policy content
    pub content: String,
    /// Applicable challenge plugin types
    pub attester_type: Vec<String>,
    /// Whether it's a default policy, defaults to false when unspecified
    pub is_default: bool,
    /// Policy version, increments by 1 by default when updated
    pub version: u32,
    /// Update time
    pub update_time: u64,
    /// Whether it's valid (0-valid, 1-invalid)
    pub valid_code: i8,
}


impl Policy {
    /// Create a new Policy instance
    pub fn new(
        name: String,
        description: String,
        content: String,
        attester_type: Vec<String>,
        is_default: Option<bool>,
    ) -> Self {
        let current_time = Utc::now().timestamp() as u64;
        let id = Uuid::new_v4();

        Policy {
            id,
            name,
            description,
            content,
            attester_type,
            is_default: is_default.unwrap_or(false),
            version: 1,
            update_time: current_time,
            valid_code: 0,
        }
    }
    
    /// Convert Policy to JSON value containing all fields
    pub fn to_full_json(&self) -> serde_json::Value {
        serde_json::json!({
            "id": self.id.to_string(),
            "name": self.name,
            "description": self.description,
            "content": &self.content,
            "attester_type": self.attester_type,
            "is_default": self.is_default,
            "version": self.version,
            "update_time": self.update_time,
            "valid_code": self.valid_code,
        })
    }
    
    /// Convert Policy to JSON value containing only basic fields
    pub fn to_base_json(&self) -> serde_json::Value {
        serde_json::json!({
            "id": self.id.to_string(),
            "name": self.name,
            "attester_type": self.attester_type,
            "update_time": self.update_time,
            "valid_code": self.valid_code,
        })
    }
}

impl From<Model> for Policy {
    fn from(model: Model) -> Self {
        let attester_type: Vec<String> = serde_json::from_value(model.attester_type)
            .unwrap_or_default();

        Policy {
            id: Uuid::parse_str(&model.policy_id).unwrap(),
            name: model.policy_name,
            description: model.policy_description,
            content: model.policy_content,
            attester_type,
            is_default: model.is_default,
            version: model.policy_version as u32,
            update_time: model.update_time.timestamp() as u64,
            valid_code: model.valid_code,
        }
    }
}